package com.booktrade.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.booktrade.constant.JwtClaimsConstant;
import com.booktrade.dto.UsersLoginDTO;
import com.booktrade.dto.UsersPasswordDTO;
import com.booktrade.dto.UsersRegisterDTO;
import com.booktrade.entity.Reviews;
import com.booktrade.entity.Users;
import com.booktrade.properties.JwtProperties;
import com.booktrade.result.Result;
import com.booktrade.service.IReviewsService;
import com.booktrade.service.IUsersService;
import com.booktrade.util.BaseContext;
import com.booktrade.util.JwtUtil;
import com.booktrade.vo.UserInfoVo;
import com.booktrade.vo.UsersVo;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 用户表，存储平台所有用户信息 前端控制器
 * </p>
 */
@RestController
@RequestMapping("/users")
@RequiredArgsConstructor
@Slf4j
public class UsersController {
    private final JwtProperties jwtProperties;
    private final IUsersService usersService;
    private final IReviewsService reviewsService;

    @Operation(summary = "用户注册")
    @PostMapping("/register")
    public Result register(@RequestBody @Validated UsersRegisterDTO usersRegisterDTO) {
        usersService.register(usersRegisterDTO);
        return Result.success();
    }

    @GetMapping()
    @Operation(summary = "根据id查询用户")
    public Result<UserInfoVo> getById() {
        Integer id = BaseContext.getCurrentId();
        Users users = usersService.getById(id);
        UserInfoVo userInfoVo = BeanUtil.copyProperties(users, UserInfoVo.class);
        List<Reviews> list = reviewsService.list(new LambdaQueryWrapper<Reviews>().eq(Reviews::getReviewerId, id).orderByDesc(Reviews::getCreatedAt));
        userInfoVo.setReviewsList(list);
        return Result.success(userInfoVo);
    }


    @GetMapping("/address")
    @Operation(summary = "查询用户地址")
    public Result<UsersVo> getAdressById(Integer id) {
        if (id == null) {
            id = BaseContext.getCurrentId();
        }
        Users users = usersService.getById(id);
        UsersVo usersVo = BeanUtil.copyProperties(users, UsersVo.class);
        return Result.success(usersVo);
    }


    @PostMapping("/login")
    @Operation(summary = "登录")
    public Result<Map<String, String>> login(@RequestBody @Validated UsersLoginDTO usersLoginDTO) {
        log.info("微信登录，用户信息为：{}", usersLoginDTO);
        Users users = usersService.getOne(new LambdaQueryWrapper<Users>().eq(Users::getUsername, usersLoginDTO.getUsername()));
        Assert.notNull(users, "用户不存在");
        Assert.isTrue(users.getPassword().equals(SecureUtil.md5(usersLoginDTO.getPassword())), "密码错误");
        Map<String, Object> Claims = new HashMap<>();
        Claims.put(JwtClaimsConstant.USER_ID, users.getId());
        String token = JwtUtil.createJWT(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), Claims);
        Map<String, String> map = new HashMap<>();
        map.put("token", token);
        return Result.success(map);
    }

    @PutMapping("/update")
    @Operation(summary = "修改用户信息")
    public Result updateById(@RequestBody Users users) {
        Users otherUsers = usersService.lambdaQuery().eq(Users::getUsername, users.getUsername()).ne(Users::getId, users.getId()).one();
        Assert.isNull(otherUsers,
                "用户名已存在");
        usersService.updateById(users);
        return Result.success();
    }

    @PutMapping("/update/password")
    @Operation(summary = "修改密码")
    public Result updatePassword(@RequestBody UsersPasswordDTO usersPasswordDTO) {
        Integer id = BaseContext.getCurrentId();
        Users users = new Users();
        users.setId(id);
        users.setPassword(SecureUtil.md5(usersPasswordDTO.getPassword()));
        usersService.updateById(users);
        return Result.success();
    }

    @DeleteMapping
    @Operation(summary = "删除用户")
    public Result removeById() {
        Integer id = BaseContext.getCurrentId();
        usersService.removeById(id);
        return Result.success();
    }

}
